package com.chengv.redismq.core;

import com.chengv.redismq.annotation.RedisMQMessageListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.NonNull;

/**
 * 延迟消息调度任务注册器
 *
 * @author chengv
 * @see RedisMQMessageListenerAnnotationPostProcessor
 */
@Slf4j
public class RedisMQDelayMessageScheduledTaskRegistrar implements ApplicationContextAware, InitializingBean {

    private ConfigurableApplicationContext applicationContext;
    private RedisMQDelayMessageScheduledTaskContainer container;
    private final RedisTemplate<String, String> redisTemplate;

    public RedisMQDelayMessageScheduledTaskRegistrar(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    }

    @Override
    public void afterPropertiesSet() {
        registerContainer(redisTemplate);
    }

    private void registerContainer(RedisTemplate<String, String> redisTemplate) {
        // 创建容器
        RedisMQDelayMessageScheduledTaskContainer container = new RedisMQDelayMessageScheduledTaskContainer(redisTemplate);

        // 注册容器 Bean
        GenericApplicationContext genericApplicationContext = (GenericApplicationContext) applicationContext;
        genericApplicationContext.registerBean(RedisMQDelayMessageScheduledTaskContainer.class, () -> container);
        //noinspection UnnecessaryLocalVariable
        RedisMQDelayMessageScheduledTaskContainer containerBean =
                genericApplicationContext.getBean(RedisMQDelayMessageScheduledTaskContainer.class);
        this.container = containerBean;
    }

    public void register(RedisMQMessageListener annotation) {
        container.register(annotation.topic());
    }
}
